home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / xvier.tar / xvier / xvier-1.0 / vier.c < prev    next >
C/C++ Source or Header  |  1992-07-28  |  17KB  |  792 lines

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/time.h>
  4.  
  5. time_t time();
  6.  
  7. #include "vier.h"
  8. #include "xvier.h"
  9.  
  10. int rows, columns, vnum;
  11. int row_col, row_1_col, row_2_col;
  12. int *brett, *weiss, *schwarz, **freip, **doublesp;
  13. int frei[MAXRC], reihenfolge[MAXRC], doubles[MAXRC];
  14. int (*pu)[4];
  15. int *_p_h_, **pp;
  16. struct oldv *stack, *sp, **zugstack;
  17. int bewertung = 0;
  18.  
  19. int zugstackp = 0, level = 2;
  20.  
  21. #define WEISS    1
  22. #define SCHWARZ  2
  23. #define W_WINS   4
  24. #define S_WINS   8
  25. #define USELESS 16
  26.  
  27. char read_char(ch)
  28. char *ch;
  29. {
  30.   if (read(0, ch, 1) < 1) {
  31.     perror("xvier_prog read failed");
  32.     exit(1);
  33.   }
  34.   return *ch;
  35. }
  36.  
  37. void write_char(ch)
  38. char ch;
  39. {
  40.   if (write(1, &ch, 1) < 1) {
  41.     perror("xvier_prog write failed");
  42.     exit(1);
  43.   }
  44. }
  45.  
  46. void w_test(pos)
  47. int pos;
  48. {
  49.   register int *p, j;
  50.   int oben;
  51.  
  52.   /* leere Position suchen */
  53.   for (p = pu[pos]; brett[*p] & (WEISS | SCHWARZ); p++);
  54.   if (brett[j = *p] & (W_WINS | USELESS))
  55.     return;
  56.   sp -> pos = brett + j;
  57.   sp++ -> value = brett[j];
  58.   brett[j] |= W_WINS;
  59.   if (*doublesp[j] == SCHWARZ &&
  60.       j > *freip[j] &&
  61.       j < row_1_col &&
  62.       !(brett[j+columns] & USELESS)) {
  63.     sp -> pos = doublesp[j];
  64.     sp++ -> value = SCHWARZ;
  65.     *doublesp[j] = 0;
  66.   }
  67.   if (!*doublesp[j] &&
  68.       ((j > *freip[j] + columns &&
  69.     (brett[(oben = j) - columns] & W_WINS)) ||
  70.        (j > *freip[j] && j < row_1_col &&
  71.     (brett[oben = j + columns] & W_WINS)))) {
  72.     register int k;
  73.  
  74.     for (k = *freip[j]; k < oben; k += columns)
  75.       if (brett[k] & S_WINS)
  76.     goto no_double;
  77.     sp -> pos = doublesp[j];
  78.     sp++ -> value = 0;
  79.     *doublesp[j] = WEISS;
  80.   }
  81.  no_double:
  82.   if (j < row_1_col &&
  83.       ((brett[oben = j] & S_WINS) ||
  84.        (j > *freip[j] && (brett[j - columns] & W_WINS)) ||
  85.        (j < row_2_col &&
  86.     (brett[oben = j + columns] & W_WINS))))
  87.     for (j = oben + columns;
  88.      j < row_col && !(brett[j] & USELESS);
  89.      j += columns) {
  90.       register int h1, h2;
  91.  
  92.       /* Vierer darueber sind nutzlos */
  93.       sp -> pos = brett + j;
  94.       sp++ -> value = brett[j];
  95.       brett[j] |= USELESS;
  96.       p = pp[j];
  97.       while ((h1 = *(p++)) >= 0) {
  98.     if ((h2 = weiss[h1]) >= 0) {
  99.       sp -> pos = &weiss[h1];
  100.       sp++ -> value = h2;
  101.       weiss[h1] = -1;
  102.       bewertung -= h2;
  103.     }
  104.     if ((h2 = schwarz[h1]) >= 0) {
  105.       sp -> pos = &schwarz[h1];
  106.       sp++ -> value = h2;
  107.       schwarz[h1] = -1;
  108.       bewertung += h2;
  109.     }
  110.       }
  111.     }
  112. }
  113.  
  114. void s_test(pos)
  115. int pos;
  116. {
  117.   register int *p, j;
  118.   int oben;
  119.  
  120.   /* leere Position suchen */
  121.   for (p = pu[pos]; brett[*p] & (WEISS | SCHWARZ); p++);
  122.   if (brett[j = *p] & (S_WINS | USELESS))
  123.     return;
  124.   sp -> pos = brett + j;
  125.   sp++ -> value = brett[j];
  126.   brett[j] |= S_WINS;
  127.   if (*doublesp[j] == WEISS &&
  128.       j > *freip[j] &&
  129.       j < row_1_col &&
  130.       !(brett[j+columns] & USELESS)) {
  131.     sp -> pos = doublesp[j];
  132.     sp++ -> value = WEISS;
  133.     *doublesp[j] = 0;
  134.   }
  135.   if (!*doublesp[j] &&
  136.       ((j > *freip[j] + columns &&
  137.     (brett[(oben = j) - columns] & S_WINS)) ||
  138.        (j > *freip[j] && j < row_1_col &&
  139.     (brett[oben = j + columns] & S_WINS)))) {
  140.     register int k;
  141.  
  142.     for (k = *freip[j]; k < oben; k += columns)
  143.       if (brett[k] & W_WINS)
  144.     goto no_double;
  145.     sp -> pos = doublesp[j];
  146.     sp++ -> value = 0;
  147.     *doublesp[j] = SCHWARZ;
  148.   }
  149.  no_double:
  150.   if (j < row_1_col &&
  151.       ((brett[oben = j] & W_WINS) ||
  152.        (j > *freip[j] && (brett[j - columns] & S_WINS)) ||
  153.        (j < row_2_col &&
  154.     (brett[oben = j + columns] & S_WINS))))
  155.     for (j = oben + columns;
  156.      j < row_col && !(brett[j] & USELESS);
  157.      j += columns) {
  158.       register int h1, h2;
  159.  
  160.       /* Vierer darueber sind nutzlos */
  161.       sp -> pos = brett + j;
  162.       sp++ -> value = brett[j];
  163.       brett[j] |= USELESS;
  164.       p = pp[j];
  165.       while ((h1 = *(p++)) >= 0) {
  166.     if ((h2 = weiss[h1]) >= 0) {
  167.       sp -> pos = &weiss[h1];
  168.       sp++ -> value = h2;
  169.       weiss[h1] = -1;
  170.       bewertung -= h2;
  171.     }
  172.     if ((h2 = schwarz[h1]) >= 0) {
  173.       sp -> pos = &schwarz[h1];
  174.       sp++ -> value = h2;
  175.       schwarz[h1] = -1;
  176.       bewertung += h2;
  177.     }
  178.       }
  179.     }
  180. }
  181.  
  182. int w_zugzwang(remain)
  183. int remain;
  184. {
  185.   register int i, pos, poslev = 7, p_s_p = 0;
  186.   int p_stack[MAXRC];
  187.  
  188.   for (i = 0; i < columns; i++) {
  189.     register int f = frei[i];
  190.  
  191.     if (f < row_col) {
  192.       if (brett[f] & W_WINS)
  193.     return 8 + 8 * remain;
  194.       if (brett[f] & S_WINS) {
  195.     pos = i;
  196.     poslev = 1;
  197.       } else if (poslev > 2) {
  198.     if (doubles[i] == WEISS) {
  199.       pos = i;
  200.       poslev = 2;
  201.     } else if (poslev > 3) {
  202.       if (f >= row_1_col ||
  203.           ((brett[f + columns] & (W_WINS | S_WINS)) == 0 &&
  204.            !doubles[i])) {
  205.         pos = i;
  206.         poslev = 3;
  207.       } else if (poslev > 4) {
  208.         if ((brett[f + columns] & (W_WINS | S_WINS)) == 0) {
  209.           pos = i;
  210.           poslev = 4;
  211.         } else if ((brett[f + columns] & S_WINS) == 0) {
  212.           p_stack[p_s_p++] = pos = i;
  213.           poslev = 5;
  214.         } else if (poslev > 6) {
  215.           pos = i;
  216.           poslev = 6;
  217.         }
  218.       }
  219.     }
  220.       }
  221.     }
  222.   }
  223.   if (poslev == 7)
  224.     return 0;
  225.   if (poslev == 5 && p_s_p > 1) {
  226.     int m;
  227.  
  228.     frei[p_stack[0]] += columns;
  229.     m = s_zugzwang(remain-1);
  230.     frei[p_stack[0]] -= columns;
  231.     for (i = 1; i < p_s_p; i++) {
  232.       register int tmp;
  233.  
  234.       frei[p_stack[i]] += columns;
  235.       if ((tmp = s_zugzwang(remain-1)) > m)
  236.     m = tmp;
  237.       frei[p_stack[i]] -= columns;
  238.     }
  239.     return m;
  240.   } else {
  241.     frei[pos] += columns;
  242.     i = s_zugzwang(remain-1);
  243.     frei[pos] -= columns;
  244.     return i;
  245.   }
  246. }
  247.  
  248. int s_zugzwang(remain)
  249. int remain;
  250. {
  251.   register int i, pos, poslev = 7, p_s_p = 0;
  252.   int p_stack[MAXRC];
  253.  
  254.   for (i = 0; i < columns; i++) {
  255.     register int f = frei[i];
  256.  
  257.     if (f < row_col) {
  258.       if (brett[f] & S_WINS)
  259.     return -8 - 8 * remain;
  260.       if (brett[f] & W_WINS) {
  261.     pos = i;
  262.     poslev = 1;
  263.       } else if (poslev > 2) {
  264.     if (doubles[i] == SCHWARZ) {
  265.       pos = i;
  266.       poslev = 2;
  267.     } else if (poslev > 3) {
  268.       if (f >= row_1_col ||
  269.           ((brett[f + columns] & (W_WINS | S_WINS)) == 0 &&
  270.            !doubles[i])) {
  271.         pos = i;
  272.         poslev = 3;
  273.       } else if (poslev > 4) {
  274.         if ((brett[f + columns] & (W_WINS | S_WINS)) == 0) {
  275.           pos = i;
  276.           poslev = 4;
  277.         } else if ((brett[f + columns] & W_WINS) == 0) {
  278.           p_stack[p_s_p++] = pos = i;
  279.           poslev = 5;
  280.         } else if (poslev > 6) {
  281.           pos = i;
  282.           poslev = 6;
  283.         }
  284.       }
  285.     }
  286.       }
  287.     }
  288.   }
  289.   if (poslev == 7)
  290.     return 0;
  291.   if (poslev == 5 && p_s_p > 1) {
  292.     int m;
  293.  
  294.     frei[p_stack[0]] += columns;
  295.     m = w_zugzwang(remain-1);
  296.     frei[p_stack[0]] -= columns;
  297.     for (i = 1; i < p_s_p; i++) {
  298.       register int tmp;
  299.  
  300.       frei[p_stack[i]] += columns;
  301.       if ((tmp = w_zugzwang(remain-1)) < m)
  302.     m = tmp;
  303.       frei[p_stack[i]] -= columns;
  304.     }
  305.     return m;
  306.   } else {
  307.     frei[pos] += columns;
  308.     i = w_zugzwang(remain-1);
  309.     frei[pos] -= columns;
  310.     return i;
  311.   }
  312. }
  313.  
  314. int comp_weiss(pos, lev, limit)
  315. int pos, lev, limit;
  316. {
  317.   register int  h1, h2, i, j, *p;
  318.   int   *frp, wert;
  319.   struct oldv *sold;
  320.  
  321.   if (brett[pos] & W_WINS)
  322.     return 50000 - lev;
  323.   /* Zug fuer Weiss ausfuehren */
  324.   sold = sp;
  325.   sp -> pos = frp = freip[pos];
  326.   sp++ -> value = *frp;
  327.   sp -> pos = brett + pos;
  328.   sp++ -> value = brett[pos];
  329.   sp -> pos = &bewertung;
  330.   sp++ -> value = bewertung;
  331.   *frp += columns;
  332.   brett[pos] |= WEISS;
  333.   p = pp[pos];
  334.   while ((h1 = *(p++)) >= 0) {
  335.     if ((h2 = weiss[h1]) >= 0) {
  336.       sp -> pos = &weiss[h1];
  337.       sp++ -> value = h2;
  338.       weiss[h1]++;
  339.       bewertung++;
  340.       if (h2 == 3)
  341.     w_test (h1);
  342.     }
  343.     if ((h2 = schwarz[h1]) >= 0) {
  344.       sp -> pos = &schwarz[h1];
  345.       sp++ -> value = h2;
  346.       schwarz[h1] = -1;
  347.       bewertung += h2;
  348.     }
  349.   }
  350.   h1 = -1;
  351.   for (i = 0; i < columns; i++) {
  352.     register int f = frei[i];
  353.  
  354.     if (f < row_col) {
  355.       if (brett[f] & S_WINS) {
  356.     wert = -49999 + lev;
  357.     goto end;
  358.       }
  359.       if (brett[f] & W_WINS)
  360.     h1 = f;
  361.     }
  362.   }
  363.   if (h1 >= 0) {
  364.     level++;
  365.     wert = comp_schwarz(h1, lev + 1, 100000);
  366.     level--;
  367.   } else if (lev >= level)
  368.     wert = bewertung + s_zugzwang(40 - lev - zugstackp);
  369.   else {
  370.     register int    zw;
  371.  
  372.     wert = 100000;
  373.     for (i = 0; i < columns; i++) {
  374.       j = frei[reihenfolge[i]];
  375.       if (j < row_col)
  376.     if ((zw = comp_schwarz (j, lev + 1, wert)) < wert)
  377.       if ((wert = zw) <= limit)
  378.         break;
  379.       /* Schwarz wird wohl den fuer ihn guenstigsten Zug auswaehlen */
  380.     }
  381.     if (wert == 100000)
  382.       wert = 0;        /* unentschieden */
  383.   }
  384.  end:
  385.   while (sp != sold) {
  386.     sp--;
  387.     *(sp -> pos) = sp -> value;
  388.   }
  389.   return (wert);
  390. }
  391.  
  392. int comp_schwarz(pos, lev, limit)
  393. int pos, lev, limit;
  394. {
  395.   register int  h1, h2, i, j, *p;
  396.   int   *frp, wert;
  397.   struct oldv *sold;
  398.  
  399.   if (brett[pos] & S_WINS)
  400.     return -50000 + lev;
  401.   /* Zug fuer Schwarz ausfuehren */
  402.   sold = sp;
  403.   sp -> pos = frp = freip[pos];
  404.   sp++ -> value = *frp;
  405.   sp -> pos = brett + pos;
  406.   sp++ -> value = brett[pos];
  407.   sp -> pos = &bewertung;
  408.   sp++ -> value = bewertung;
  409.   *frp += columns;
  410.   brett[pos] |= SCHWARZ;
  411.   p = pp[pos];
  412.   while ((h1 = *(p++)) >= 0) {
  413.     if ((h2 = schwarz[h1]) >= 0) {
  414.       sp -> pos = &schwarz[h1];
  415.       sp++ -> value = h2;
  416.       schwarz[h1]++;
  417.       bewertung--;
  418.       if (h2 == 3)
  419.     s_test (h1);
  420.     }
  421.     if ((h2 = weiss[h1]) >= 0) {
  422.       sp -> pos = &weiss[h1];
  423.       sp++ -> value = h2;
  424.       weiss[h1] = -1;
  425.       bewertung -= h2;
  426.     }
  427.   }
  428.   h1 = -1;
  429.   for (i = 0; i < columns; i++) {
  430.     register int f = frei[i];
  431.  
  432.     if (f < row_col) {
  433.       if (brett[f] & W_WINS) {
  434.     wert = 49999 - lev;
  435.     goto end;
  436.       }
  437.       if (brett[f] & S_WINS)
  438.     h1 = f;
  439.     }
  440.   }
  441.   if (h1 >= 0) {
  442.     level++;
  443.     wert = comp_weiss(h1, lev + 1, -100000);
  444.     level--;
  445.   } else if (lev >= level)
  446.     wert = bewertung + w_zugzwang(40 - lev - zugstackp);
  447.   else {
  448.     register int    zw;
  449.  
  450.     wert = -100000;
  451.     for (i = 0; i < columns; i++) {
  452.       j = frei[reihenfolge[i]];
  453.       if (j < row_col)
  454.     if ((zw = comp_weiss (j, lev + 1, wert)) > wert)
  455.       if ((wert = zw) >= limit)
  456.         break;
  457.     }
  458.     if (wert == -100000)
  459.       wert = 0;        /* unentschieden */
  460.   }
  461.  end:
  462.   while (sp != sold) {
  463.     sp--;
  464.     *(sp -> pos) = sp -> value;
  465.   }
  466.   return (wert);
  467. }
  468.  
  469. int main(argc, argv)
  470. int argc;
  471. char **argv;
  472. {
  473.   int  i, j, h1, zj, *p, wert, zi;
  474.   char ch, buf[10];
  475.   int  same[MAXRC], same_n;
  476.  
  477.   if (argc != 3 ||
  478.       (rows = atoi(argv[1])) < 4 || rows > MAXRC ||
  479.       (columns = atoi(argv[2])) < 4 || columns > MAXRC) {
  480.     fprintf(stderr, "Usage: %s <rows> <columns>\n", *argv);
  481.     exit(1);
  482.   }
  483.   vierinit();
  484.   sprintf(buf, "%dR%dC", rows, columns);
  485.   for (i = 0; buf[i] != '\0'; i++)
  486.     write_char(buf[i]);
  487.   srand((int) time(NULL));
  488.   while (1) {
  489.   mensch:
  490.     read_char(&ch);
  491.     switch (ch) {
  492.     case '0': case '1': case '2': case '3': case '4':
  493.     case '5': case '6': case '7': case '8': case '9':
  494.       write_char(ch);
  495.       level = ch - '0' + 2;
  496.       break;
  497.     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
  498.     case 'h': case 'i': case 'j': case 'k': case 'l': case 'm':
  499.       if (ch - 'a' >= columns ||
  500.       (j = frei[ch - 'a']) >= row_col) {
  501.     write_char('x');
  502.     break;
  503.       }
  504.       if (brett[j] & W_WINS) {
  505.     write_char('w');
  506.     while (read_char(&ch) != 'u')
  507.       switch (ch) {
  508.       case '0': case '1': case '2': case '3': case '4':
  509.       case '5': case '6': case '7': case '8': case '9':
  510.         write_char(ch);
  511.         level = ch - '0' + 2;
  512.         break;
  513.       case 'n':
  514.         goto newgame;
  515.       default:
  516.         write_char('x');
  517.         break;
  518.       }
  519.     write_char('v');
  520.     break;
  521.       }
  522.       zugstack[zugstackp++] = sp;
  523.       sp -> pos = brett + j;
  524.       sp++ -> value = brett[j];
  525.       sp -> pos = frei + ch - 'a';
  526.       sp++ -> value = frei[ch - 'a'];
  527.       sp -> pos = &bewertung;
  528.       sp++ -> value = bewertung;
  529.       brett[j] |= WEISS;
  530.       frei[ch - 'a'] += columns;
  531.       p = pp[j];
  532.       while ((h1 = *(p++)) >= 0) {
  533.     if ((weiss[h1]) >= 0) {
  534.       sp -> pos = weiss + h1;
  535.       sp++ -> value = weiss[h1];
  536.       weiss[h1]++;
  537.       bewertung++;
  538.       if (weiss[h1] == 4)
  539.         w_test(h1);
  540.     }
  541.     if ((schwarz[h1]) >= 0) {
  542.       sp -> pos = schwarz + h1;
  543.       sp++ -> value = schwarz[h1];
  544.       bewertung += schwarz[h1];
  545.       schwarz[h1] = -1;
  546.     }
  547.       }
  548.     computer:
  549.       same_n = 0;
  550.       for (i = 0; i < columns; i++) {
  551.     int f = frei[i];
  552.     
  553.     if (f < row_col) {
  554.       if (brett[f] & S_WINS) {
  555.         zi = i;
  556.         goto calculate_end;
  557.       }
  558.       if (brett[f] & W_WINS)
  559.         same[same_n++] = i;
  560.     }
  561.       }
  562.       if (same_n == 0) {
  563.     wert = 100000;
  564.     for (i = 0; i < columns; i++) {
  565.       register int zw;
  566.       
  567.       if ((j = frei[reihenfolge[i]]) < row_col)
  568.         if ((zw = comp_schwarz (j, 0, wert + 1)) < wert) {
  569.           wert = zw;
  570.           same_n = 1;
  571.           same[0] = reihenfolge[i];
  572.         } else if (zw == wert)
  573.           same[same_n++] = reihenfolge[i];
  574.     }
  575.       }
  576.       if (same_n == 0) {
  577.     write_char('z');
  578.     while (read_char(&ch) != 'u')
  579.       switch (ch) {
  580.       case '0': case '1': case '2': case '3': case '4':
  581.       case '5': case '6': case '7': case '8': case '9':
  582.         write_char(ch);
  583.         level = ch - '0' + 2;
  584.         break;
  585.       case 'n':
  586.         goto newgame;
  587.       default:
  588.         write_char('x');
  589.         break;
  590.       }
  591.     write_char('v');
  592.     zugstackp--;
  593.     while (sp != zugstack[zugstackp]) {
  594.       sp--;
  595.       *(sp -> pos) = sp -> value;
  596.     }
  597.     break;
  598.       }
  599.       if (same_n == 1)
  600.     zi = same[0];
  601.       else
  602.     zi = same[rand() % same_n];
  603.     calculate_end:
  604.       zj = frei[zi];
  605.       if (brett[zj] & S_WINS) {
  606.     write_char('A' + zi);
  607.     while (read_char(&ch) != 'u')
  608.       switch (ch) {
  609.       case '0': case '1': case '2': case '3': case '4':
  610.       case '5': case '6': case '7': case '8': case '9':
  611.         write_char(ch);
  612.         level = ch - '0' + 2;
  613.         break;
  614.       case 'n':
  615.         goto newgame;
  616.       default:
  617.         write_char('x');
  618.         break;
  619.       }
  620.     write_char('u');
  621.     zugstackp--;
  622.     while (sp != zugstack[zugstackp]) {
  623.       sp--;
  624.       *(sp -> pos) = sp -> value;
  625.     }
  626.     break;
  627.       }
  628.       zugstack[zugstackp++] = sp;
  629.       sp -> pos = brett + zj;
  630.       sp++ -> value = brett[zj];
  631.       sp -> pos = frei + zi;
  632.       sp++ -> value = zj;
  633.       sp -> pos = &bewertung;
  634.       sp++ -> value = bewertung;
  635.       brett[zj] |= SCHWARZ;
  636.       frei[zi] += columns;
  637.       p = pp[zj];
  638.       while ((h1 = *(p++)) >= 0) {
  639.     if ((schwarz[h1]) >= 0) {
  640.       sp -> pos = schwarz + h1;
  641.       sp++ -> value = schwarz[h1];
  642.       schwarz[h1]++;
  643.       bewertung--;
  644.       if (schwarz[h1] == 4)
  645.         s_test(h1);
  646.     }
  647.     if ((weiss[h1]) >= 0) {
  648.       sp -> pos = weiss + h1;
  649.       sp++ -> value = weiss[h1];
  650.       bewertung -= weiss[h1];
  651.       weiss[h1] = -1;
  652.     }
  653.       }
  654.       if (frei[zi] < row_col && (brett[frei[zi]] & USELESS)) {
  655.     /* user didn't recognize a double */
  656.     for (i = frei[zi]; i < row_col; i+= columns) {
  657.       int w_wins = 0, s_wins = 0;
  658.  
  659.       sp -> pos = brett + i;
  660.       sp++ -> value = brett[i];
  661.       brett[i] = 0;
  662.       p = pp[i];
  663.       while ((h1 = *(p++)) >= 0) {
  664.         int wval = 1, sval = 1;
  665.  
  666.         for (j = 0; j < 4; j++) {
  667.           if (brett[pu[h1][j]] & USELESS) {
  668.         wval = -1;
  669.         sval = -1;
  670.           } else if (brett[pu[h1][j]] & WEISS) {
  671.         if (wval > 0)
  672.           wval++;
  673.           } else if (brett[pu[h1][j]] & SCHWARZ) {
  674.         if (sval > 0)
  675.           sval++;
  676.           }
  677.         }
  678.         if (wval > 0) {
  679.           bewertung += wval;
  680.           sp -> pos = weiss + h1;
  681.           sp++ -> value = weiss[h1];
  682.           weiss[h1] = wval;
  683.           if (wval == 4)
  684.         w_wins = 1;
  685.         }
  686.         if (sval > 0) {
  687.           bewertung -= sval;
  688.           sp -> pos = schwarz + h1;
  689.           sp++ -> value = schwarz[h1];
  690.           schwarz[h1] = sval;
  691.           if (sval == 4)
  692.         s_wins = 1;
  693.         }
  694.       }
  695.       if (w_wins && s_wins) {
  696.         brett[i] |= (W_WINS | S_WINS);
  697.         if (i > frei[zi] + columns) {
  698.           if (brett[i - columns] & W_WINS) {
  699.         if (*doublesp[i] != WEISS) {
  700.           sp -> pos = doublesp[i];
  701.           sp++ -> value = *doublesp[i];
  702.           *doublesp[i] = WEISS;
  703.         }
  704.           } else if (brett[i - columns] & S_WINS) {
  705.         if (*doublesp[i] != SCHWARZ) {
  706.           sp -> pos = doublesp[i];
  707.           sp++ -> value = *doublesp[i];
  708.           *doublesp[i] = SCHWARZ;
  709.         }
  710.           }
  711.         }
  712.         break;
  713.       } else if (w_wins) {
  714.         brett[i] |= W_WINS;
  715.         if (i > frei[zi] + columns && (brett[i - columns] & W_WINS)) {
  716.           if (*doublesp[i] != WEISS) {
  717.         sp -> pos = doublesp[i];
  718.         sp++ -> value = *doublesp[i];
  719.         *doublesp[i] = WEISS;
  720.           }
  721.           break;
  722.         }
  723.       } else if (s_wins) {
  724.         brett[i] |= S_WINS;
  725.         if (i > frei[zi] + columns  && (brett[i - columns] & S_WINS)) {
  726.           if (*doublesp[i] != SCHWARZ) {
  727.         sp -> pos = doublesp[i];
  728.         sp++ -> value = *doublesp[i];
  729.         *doublesp[i] = SCHWARZ;
  730.           }
  731.           break;
  732.         }
  733.       }
  734.     }
  735.       }
  736.       for (i = 0; i < columns; i++)
  737.     if (frei[i] < row_col) {
  738.       write_char('a' + zi);
  739.       goto mensch;
  740.     }
  741.       /* unentschieden */
  742.       write_char('N' + zi);
  743.       while (read_char(&ch) != 'u')
  744.     switch (ch) {
  745.     case '0': case '1': case '2': case '3': case '4':
  746.     case '5': case '6': case '7': case '8': case '9':
  747.       write_char(ch);
  748.       level = ch - '0' + 2;
  749.       break;
  750.     case 'n':
  751.       goto newgame;
  752.     default:
  753.       write_char('x');
  754.       break;
  755.     }
  756.       write_char('u');
  757.       zugstackp -= 2;
  758.       while (sp != zugstack[zugstackp]) {
  759.     sp--;
  760.     *(sp -> pos) = sp -> value;
  761.       }
  762.       break;
  763.     case 'n':
  764.     newgame:
  765.       write_char('n');
  766.       zugstackp = 0;
  767.       while (sp != stack) {
  768.     sp--;
  769.     *(sp -> pos) = sp -> value;
  770.       }
  771.       break;
  772.     case 'u':
  773.       if (zugstackp < 2)
  774.     goto newgame;
  775.       write_char('u');
  776.       zugstackp -= 2;
  777.       while (sp != zugstack[zugstackp]) {
  778.     sp--;
  779.     *(sp -> pos) = sp -> value;
  780.       }
  781.       break;
  782.     case 's':
  783.       if (zugstackp == 0)
  784.     goto computer;
  785.       /* else fall through */
  786.     default:
  787.       write_char('x');
  788.       break;
  789.     }
  790.   }
  791. }
  792.